<template>
  <div class="form-builder">
    <!-- 左侧组件库 -->
    <ComponentLibrary @drag-start="handleDragStart" />

    <!-- 中间画布区域 -->
    <CanvasArea
      ref="canvasRef"
      :all-components="canvasComponents"
      :selected-component="selectedComponent"
      :alignment-guides="alignmentGuides"
      :mutex-state="mutexState"
      :relate-state="relateState"
      :loading="loading"
      :drag-hover-state="dragHoverState"
      :drag-shadow="dragShadow"
      @drop="handleDrop"
      @start-drag="startComponentDrag"
      @start-resize="startComponentResize"
      @clear-canvas="clearCanvas"
      @preview-form="previewForm"
      @save-form="saveForm"
      @export-json="exportJson"
      @clear-selection="clearSelection"
      @move-to-top="handleMoveToTop"
      @move-to-bottom="handleMoveToBottom"
      @drag-hover="handleDragHover"
      @drag-leave="handleDragLeave"
      @select-child-component="selectComponent"
      @select-component="selectComponent"
    />

    <!-- 右侧属性配置面板 -->
    <PropertyPanel
      :selected-component="selectedComponent"
      :all-components="canvasComponents"
      @update-props="updateComponentProps"
      @update-size="updateComponentSize"
      @update-component="handleUpdateComponent"
    />

    <!-- 预览弹窗 -->
    <PreviewDialog
      v-if="previewVisible"
      v-model="previewVisible"
      :components="canvasComponents"
      @submit="submitPreview"
    />

    <!-- 保存表单弹窗 -->
    <SaveFormDialog
      v-model="saveFormVisible"
      :components="canvasComponents"
      @save="handleSaveForm"
    />

    <!-- 互斥设置弹窗 -->
    <MutexDialog
      v-model="mutexDialogVisible"
      :mutex-config="
        selectedComponent?.props.mutexConfig || { enabled: false, rules: [] }
      "
      :component-options="selectedComponent?.props.options || []"
      :all-components="canvasComponents"
      :current-component="selectedComponent"
      @confirm="handleMutexConfirm"
    />
    
    <!-- 选项关联弹窗 -->
    <RelateDialog
      v-model="relateDialogVisible"
      :relate-config="
        selectedComponent?.props.relateConfig || { enabled: false, rules: [] }
      "
      :component-options="selectedComponent?.props.options || []"
      :all-components="canvasComponents"
      :current-component-id="selectedComponent?.id || ''"
      @confirm="handleRelateConfirm"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { useRoute } from "vue-router";
import ComponentLibrary from "./components/ComponentLibrary.vue";
import type {
  ComponentConfig,
  CanvasComponent,
  MutexRule,
  MutexConfig,
  RelateConfig,
} from "./types";
import CanvasArea from "./components/CanvasArea.vue";
import PropertyPanel from "./components/PropertyPanel.vue";
import PreviewDialog from "./components/PreviewDialog.vue";
import SaveFormDialog from "./components/SaveFormDialog.vue";
import MutexDialog from "./components/MutexDialog.vue";
import RelateDialog from "./components/RelateDialog.vue";
import { saveQuestionJson, getQuestionById } from "@/api/home";
import { getTypeName } from "./constants";
import { EventBus } from "@/utils/eventBus";
import _ from "lodash";

const emit = defineEmits<{
  "select-child-component": [component: CanvasComponent];
}>();

// 路由参数
const route = useRoute();

// 响应式数据
const canvasRef = ref();
const canvasComponents = ref<CanvasComponent[]>([]);
const selectedComponent = ref<CanvasComponent | null>(null);
const previewVisible = ref(false);
const saveFormVisible = ref(false);
const mutexDialogVisible = ref(false);
const relateDialogVisible = ref(false);
const loading = ref(false);

// 拖拽悬停状态
const dragHoverState = ref<{
  isHovering: boolean;
  gridComponent: CanvasComponent | null;
  gridItemIndex: number;
}>({
  isHovering: false,
  gridComponent: null,
  gridItemIndex: -1,
});

// 拖拽阴影状态
const dragShadow = ref<{
  visible: boolean;
  x: number;
  y: number;
  width: number | string;
  height: number | string;
}>({
  visible: false,
  x: 0,
  y: 0,
  width: '100%',
  height: '30px',
});

// 互斥状态管理
const mutexState = ref<Map<string, boolean>>(new Map());

// 关联状态管理
const relateState = ref<RelateConfig[]>([]);

// 拖拽相关状态
const dragState = reactive({
  isDragging: false,
  isMouseDown: false,
  dragComponent: null as CanvasComponent | null,
  startPosition: { x: 0, y: 0 },
  offset: { x: 0, y: 0 },
  originalPosition: { x: 0, y: 0 },
  dragThreshold: 5, // 拖拽阈值，超过这个距离才开始拖拽
});

// 调整尺寸相关状态
const resizeState = reactive({
  isResizing: false,
  resizeComponent: null as CanvasComponent | null,
  resizeDirection: "",
  startPosition: { x: 0, y: 0 },
  originalSize: { width: 0, height: 0 },
  originalPosition: { x: 0, y: 0 },
});

// 对齐线状态
const alignmentGuides = reactive({
  vertical: null as number | null,
  horizontal: null as number | null,
});

// 当前拖拽的组件数据
const currentDragComponent = ref<ComponentConfig | null>(null);

// 从组件库拖拽开始
const handleDragStart = (event: DragEvent, component: ComponentConfig) => {
  currentDragComponent.value = component;
  console.log(currentDragComponent.value);
  if (event.dataTransfer) {
    event.dataTransfer.setData("component", JSON.stringify(component));
    event.dataTransfer.effectAllowed = "copy";
  }
};

// 放置到画布
const handleDrop = (event: DragEvent) => {
  event.preventDefault();

  if (!event.dataTransfer) return;

  const componentData = event.dataTransfer.getData("component");
  if (!componentData) return;

  try {
    const component: ComponentConfig = JSON.parse(componentData);
    const canvasRect = canvasRef.value?.getCanvasRect();

    if (!canvasRect) return;

    const x = event.clientX - canvasRect.left;
    const y = event.clientY - canvasRect.top;

    // 检查是否拖拽到栅格组件上
    const gridDropResult = checkGridDrop(x, y);

    if (gridDropResult.isGridDrop && gridDropResult.gridComponent) {
      // 拖拽到栅格组件上，将组件添加到栅格中
      const gridComponent = gridDropResult.gridComponent;
      const gridItemIndex = gridDropResult.gridItemIndex;

      // 生成唯一的字段名
      const uniqueField = generateUniqueField(
        component.defaultProps.field,
        component.type
      );

      const newComponent: CanvasComponent = {
        id: generateId(),
        type: component.type,
        props: {
          ...component.defaultProps,
          field: uniqueField,
        },
        position: { x: 0, y: 0 }, // 栅格内组件的位置将在渲染时计算
        size: { ...component.defaultSize },
        value: getDefaultValue(component.type),
        parentId: gridComponent.id, // 标记父组件
        gridItemIndex: gridItemIndex, // 标记在栅格中的位置
      };

      // 将组件添加到栅格组件的子组件列表中
      if (!gridComponent.children) {
        gridComponent.children = [];
      }
      gridComponent.children.push(newComponent);

      // 同时添加到主组件列表（用于统一管理）
      // canvasComponents.value.push(newComponent);
      selectComponent(newComponent);

      ElMessage.success(`组件已添加到栅格第${gridItemIndex + 1}列`);

      // 清除拖拽悬停状态
      dragHoverState.value = {
        isHovering: false,
        gridComponent: null,
        gridItemIndex: -1,
      };
      return;
    }

    // 使用计算出的位置放置组件
    const dropPosition = calculateDropPosition();
    
    const finalX = dropPosition.x;
    const finalY = dropPosition.y;

    // 生成唯一的字段名
    const uniqueField = generateUniqueField(
      component.defaultProps.field,
      component.type
    );

    const newComponent: CanvasComponent = {
      id: generateId(),
      type: component.type,
      props: {
        ...component.defaultProps,
        field: uniqueField,
      },
      position: { x: finalX, y: finalY },
      size: { ...component.defaultSize },
      value: getDefaultValue(component.type),
    };

    canvasComponents.value.push(newComponent);
    selectComponent(newComponent);
    
    // 清理拖拽状态
    // currentDragComponent.value = null;
    dragShadow.value = {
      visible: false,
      x: 0,
      y: 0,
      width: 0,
      height: 0,
    };
  } catch (error) {
    console.error("解析组件数据失败:", error);
    // 清理拖拽状态
    // currentDragComponent.value = null;
  }
};

// 生成唯一ID
const generateId = (): string => {
  return (
    "component_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9)
  );
};

// 生成唯一字段名
const generateUniqueField = (
  baseField: string,
  componentType: string
): string => {
  const timestamp = Date.now();
  const randomSuffix = Math.random().toString(36).substr(2, 4);
  return `${baseField}_${timestamp}_${randomSuffix}`;
};

// 获取组件默认值
const getDefaultValue = (type: string): any => {
  // 统一按照 input 组件的标准，所有组件默认值都为空字符串
  switch (type) {
    case "checkbox":
      return []; // 多选框保持数组类型
    case "radio":
      return ""; // 单选框改为空字符串
    case "select":
      return ""; // 下拉选择改为空字符串
    case "number":
      return ""; // 数字输入改为空字符串
    case "date":
      return ""; // 日期选择保持空字符串
    default:
      return ""; // 其他所有组件都为空字符串
  }
};

// 检查碰撞
const checkCollision = (
  x: number,
  y: number,
  width: number,
  height: number,
  excludeId?: string
): boolean => {
  return canvasComponents.value.some((component: CanvasComponent) => {
    if (excludeId && component.id === excludeId) return false;

    const comp: CanvasComponent = component;

    // 跳过有父组件的组件（嵌套组件不参与碰撞检测）
    if (comp.parentId) return false;

    // 考虑CanvasArea中canvas-component的padding (2px)
    const padding = 2;
    const compEffectiveWidth = comp.size.width + padding * 2;
    const compEffectiveHeight = comp.size.height + padding * 2;

    // 工具栏高度（组件上方26px）
    const toolbarHeight = 0;

    // 调整组件位置，忽略工具栏区域
    const adjustedCompY = comp.position.y + toolbarHeight;
    const adjustedCompHeight = compEffectiveHeight - toolbarHeight;

    // 计算重叠区域
    const overlapX = Math.max(
      0,
      Math.min(x + width, comp.position.x + compEffectiveWidth) -
        Math.max(x, comp.position.x)
    );
    const overlapY = Math.max(
      0,
      Math.min(y + height, adjustedCompY + adjustedCompHeight) -
        Math.max(y, adjustedCompY)
    );

    // 如果有重叠区域，则发生碰撞
    return overlapX > 0 && overlapY > 0;
  });
};

// 检查是否拖拽到栅格组件上
const checkGridDrop = (
  x: number,
  y: number
): {
  isGridDrop: boolean;
  gridComponent: CanvasComponent | null;
  gridItemIndex: number;
} => {
  const canvasRect = canvasRef.value?.getCanvasRect();
  for (const component of canvasComponents.value) {
    if (component.type === "grid") {
      const padding = 2;
      // 计算显示宽度：考虑 full/custom 宽度
      let displayedWidth = component.size.width;
      if (
        component.props.widthType === "custom" &&
        component.props.customWidth
      ) {
        displayedWidth = component.props.customWidth;
      } else if (component.props.widthType === "full") {
        displayedWidth = canvasRect ? canvasRect.width : component.size.width;
      }
      const compEffectiveWidth = displayedWidth + padding * 2;
      const compEffectiveHeight = component.size.height + padding * 2;

      // 检查是否在栅格组件范围内
      if (
        x >= component.position.x - padding &&
        x <= component.position.x + compEffectiveWidth + padding &&
        y >= component.position.y - padding &&
        y <= component.position.y + compEffectiveHeight + padding
      ) {
        // 计算在栅格内容区域中的相对位置（扣除外层 padding）
        const innerLeft = component.position.x + padding;
        const innerTop = component.position.y + padding;
        const innerWidth = displayedWidth;
        const innerHeight = component.size.height;

        const relativeX = x - innerLeft;
        const relativeY = y - innerTop;

        // 计算栅格列数
        const gridColumns = component.props.gridColumns || 2;
        const gridGap = component.props.gridGap || 16;

        // 列宽计算（精确考虑间距）
        const columnWidth =
          (innerWidth - gridGap * (gridColumns - 1)) / gridColumns;
        const slot = columnWidth + gridGap;
        const clampedX = Math.max(0, Math.min(relativeX, innerWidth - 1));

        // 若落在列内：按 slot 取 floor；若落在 gap 内：按最接近列取 round
        let gridItemIndex = Math.round(clampedX / slot);

        // 避免 round 越界与列内误差：当落在列区间前半时回退
        // 计算当前所在 slot 左边界与相对位置
        const approxSlotIndex = Math.floor(clampedX / slot);
        const slotStart = approxSlotIndex * slot;
        const posInSlot = clampedX - slotStart;
        if (posInSlot <= columnWidth) {
          gridItemIndex = approxSlotIndex;
        }

        if (gridItemIndex < 0) gridItemIndex = 0;
        if (gridItemIndex > gridColumns - 1) gridItemIndex = gridColumns - 1;
        // 调试：console.log('grid hover', { relativeX, innerWidth, gridColumns, gridItemIndex })
        return { isGridDrop: true, gridComponent: component, gridItemIndex };
      }
    }
  }

  return { isGridDrop: false, gridComponent: null, gridItemIndex: -1 };
};

// 选择组件
const selectComponent = (component: CanvasComponent) => {
  console.log("FormBuilder 选择组件:", component);

  // 检查是否是栅格内的子组件
  if (component.parentId) {
    // 如果是子组件，直接设置为选中状态
    console.log("选中栅格内子组件:", component);
    selectedComponent.value = component;
    return;
  }

  // 直接引用canvasComponents中的组件
  const index = canvasComponents.value.findIndex(
    (comp) => comp.id === component.id
  );
  if (index !== -1) {
    selectedComponent.value = canvasComponents.value[index];
  } else {
    selectedComponent.value = component;
  }

  console.log("当前选中的组件:", selectedComponent.value);
};

// 开始拖拽画布中的组件
const startComponentDrag = (event: MouseEvent, component: CanvasComponent) => {
  console.log("startComponentDrag");
  if (event.button !== 0) return;

  // 跳过嵌套组件的拖拽
  if (component.parentId) return;
  event.preventDefault();

  // 先选中组件
  // selectComponent(component);

  // 获取画布边界信息
  const canvasRect = canvasRef.value?.getCanvasRect();
  if (!canvasRect) return;

  // 记录鼠标按下状态，但不立即开始拖拽
  dragState.isMouseDown = true;
  dragState.dragComponent = component;
  dragState.startPosition = { x: event.clientX, y: event.clientY };
  dragState.offset = {
    x: event.clientX - canvasRect.left - component.position.x,
    y: event.clientY - canvasRect.top - component.position.y,
  };
  dragState.originalPosition = { ...component.position };

  document.addEventListener("mousemove", handleMouseMove);
  document.addEventListener("mouseup", handleMouseUp);
};

// 开始调整组件尺寸
const startComponentResize = (
  event: MouseEvent,
  component: CanvasComponent,
  direction: string
) => {
  console.log("startComponentResize:", event, component, direction);

  if (event.button !== 0) return;

  // 跳过嵌套组件的尺寸调整
  if (component.parentId) return;

  event.preventDefault();

  // 选中组件
  selectComponent(component);

  // 记录调整尺寸状态
  resizeState.isResizing = true;
  resizeState.resizeComponent = component;
  resizeState.resizeDirection = direction;
  resizeState.startPosition = { x: event.clientX, y: event.clientY };

  // 根据宽度类型确定原始尺寸
  let originalWidth = component.size.width;
  if (component.props.widthType === "custom" && component.props.customWidth) {
    originalWidth = component.props.customWidth;
  }

  resizeState.originalSize = {
    width: originalWidth,
    height: component.size.height,
  };
  resizeState.originalPosition = { ...component.position };

  document.addEventListener("mousemove", handleResizeMove);
  document.addEventListener("mouseup", handleResizeUp);
};

// 处理鼠标移动
const handleMouseMove = (event: MouseEvent) => {
  if (!dragState.isMouseDown || !dragState.dragComponent) return;

  // 检查是否超过拖拽阈值
  const deltaX = Math.abs(event.clientX - dragState.startPosition.x);
  const deltaY = Math.abs(event.clientY - dragState.startPosition.y);
  const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

  // 如果还没开始拖拽且移动距离超过阈值，则开始拖拽
  if (!dragState.isDragging && distance > dragState.dragThreshold) {
    dragState.isDragging = true;
  }

  // 只有在真正拖拽时才更新位置
  if (!dragState.isDragging) return;

  const canvasRect = canvasRef.value?.getCanvasRect();
  if (!canvasRect) return;

  const x = event.clientX - canvasRect.left - dragState.offset.x;
  const y = event.clientY - canvasRect.top - dragState.offset.y;

  // 边界检查 - 考虑组件的padding和宽度类型
  const padding = 2;
  let effectiveWidth = dragState.dragComponent.size.width + padding * 2;
  const effectiveHeight = dragState.dragComponent.size.height + padding * 2;

  // 对于铺满宽度的组件，使用画布宽度作为有效宽度
  if (dragState.dragComponent.props.widthType === "full") {
    effectiveWidth = canvasRect.width;
  }

  const maxX = canvasRect.width - effectiveWidth;

  const newX = Math.max(0, Math.min(x, maxX));
  const newY = Math.max(0, y); // 移除向下移动的边界限制，只限制向上移动

  // 更新组件位置
  dragState.dragComponent.position.x = newX;
  dragState.dragComponent.position.y = newY;

  // 实时检查碰撞并更新碰撞状态
  const hasCollision = checkCollision(
    newX,
    newY,
    dragState.dragComponent.size.width,
    dragState.dragComponent.size.height,
    dragState.dragComponent.id
  );

  // 更新组件的碰撞状态
  dragState.dragComponent.isColliding = hasCollision;

  // 显示对齐线
  showAlignmentGuides(newX, newY, dragState.dragComponent);
};

// 处理鼠标释放
const handleMouseUp = () => {
  // 如果正在拖拽，则处理拖拽结束逻辑
  if (dragState.isDragging && dragState.dragComponent) {
    // 检查碰撞
    const component = dragState.dragComponent;
    if (
      checkCollision(
        component.position.x,
        component.position.y,
        component.size.width,
        component.size.height,
        component.id
      )
    ) {
      // 恢复到原始位置
      component.position = { ...dragState.originalPosition };
      ElMessage.warning("组件位置重叠，已恢复到原位置");
    }

    // 清除碰撞状态
    component.isColliding = false;
  }

  // 清理状态
  dragState.isDragging = false;
  dragState.isMouseDown = false;
  dragState.dragComponent = null;
  alignmentGuides.vertical = null;
  alignmentGuides.horizontal = null;

  document.removeEventListener("mousemove", handleMouseMove);
  document.removeEventListener("mouseup", handleMouseUp);
};

// 处理调整尺寸时的鼠标移动
const handleResizeMove = (event: MouseEvent) => {
  if (!resizeState.isResizing || !resizeState.resizeComponent) return;

  const deltaX = event.clientX - resizeState.startPosition.x;
  const deltaY = event.clientY - resizeState.startPosition.y;

  const component = resizeState.resizeComponent;
  const direction = resizeState.resizeDirection;

  // 根据调整方向计算新的尺寸和位置
  let newWidth = resizeState.originalSize.width;
  let newHeight = resizeState.originalSize.height;
  let newX = resizeState.originalPosition.x;
  let newY = resizeState.originalPosition.y;

  switch (direction) {
    case "right":
      newWidth = Math.max(100, resizeState.originalSize.width + deltaX);
      break;
    case "left":
      newWidth = Math.max(100, resizeState.originalSize.width - deltaX);
      newX =
        resizeState.originalPosition.x +
        (resizeState.originalSize.width - newWidth);
      break;
    case "top":
      newHeight = Math.max(30, resizeState.originalSize.height - deltaY);
      newY =
        resizeState.originalPosition.y +
        (resizeState.originalSize.height - newHeight);
      break;
    case "bottom":
      newHeight = Math.max(30, resizeState.originalSize.height + deltaY);
      break;
    case "top-left":
      newWidth = Math.max(100, resizeState.originalSize.width - deltaX);
      newHeight = Math.max(30, resizeState.originalSize.height - deltaY);
      newX =
        resizeState.originalPosition.x +
        (resizeState.originalSize.width - newWidth);
      newY =
        resizeState.originalPosition.y +
        (resizeState.originalSize.height - newHeight);
      break;
    case "top-right":
      newWidth = Math.max(100, resizeState.originalSize.width + deltaX);
      newHeight = Math.max(30, resizeState.originalSize.height - deltaY);
      newY =
        resizeState.originalPosition.y +
        (resizeState.originalSize.height - newHeight);
      break;
    case "bottom-left":
      newWidth = Math.max(100, resizeState.originalSize.width - deltaX);
      newHeight = Math.max(30, resizeState.originalSize.height + deltaY);
      newX =
        resizeState.originalPosition.x +
        (resizeState.originalSize.width - newWidth);
      break;
    case "bottom-right":
      newWidth = Math.max(100, resizeState.originalSize.width + deltaX);
      newHeight = Math.max(30, resizeState.originalSize.height + deltaY);
      break;
  }

  // 获取画布边界
  const canvasRect = canvasRef.value?.getCanvasRect();
  if (canvasRect) {
    // 边界检查 - 考虑组件的padding和宽度类型
    const padding = 2;
    let effectiveWidth = newWidth + padding * 2;

    // 对于铺满宽度的组件，使用画布宽度作为有效宽度
    if (component.props.widthType === "full") {
      effectiveWidth = canvasRect.width;
    }

    const maxX = canvasRect.width - effectiveWidth;

    // 水平边界检查
    newX = Math.max(0, Math.min(newX, maxX));
    
    // 垂直边界检查 - 只限制顶部，允许底部无限扩展
    newY = Math.max(0, newY);
    
    // 对于向上拖拽的情况，需要确保组件不会超出画布顶部
    if (direction.includes('top') && newY + newHeight > resizeState.originalPosition.y + resizeState.originalSize.height) {
      // 如果向上拖拽导致组件底部超出原始位置，则限制拖拽
      const maxAllowedY = resizeState.originalPosition.y + resizeState.originalSize.height - newHeight;
      newY = Math.max(0, maxAllowedY);
    }
  }

  // 更新组件尺寸和位置
  component.size.width = newWidth;
  component.size.height = newHeight;
  component.position.x = newX;
  component.position.y = newY;

  // 如果组件是自定义宽度类型，同步更新customWidth
  if (component.props.widthType === "custom") {
    component.props.customWidth = newWidth;
  }
};

// 处理调整尺寸时的鼠标释放
const handleResizeUp = () => {
  if (!resizeState.isResizing || !resizeState.resizeComponent) return;

  // 检查调整尺寸后是否与其他组件重叠
  const component = resizeState.resizeComponent;
  if (
    checkCollision(
      component.position.x,
      component.position.y,
      component.size.width,
      component.size.height,
      component.id
    )
  ) {
    // 恢复到原始尺寸和位置
    component.size = { ...resizeState.originalSize };
    component.position = { ...resizeState.originalPosition };

    // 如果组件是自定义宽度类型，同步恢复customWidth
    if (component.props.widthType === "custom") {
      component.props.customWidth = resizeState.originalSize.width;
    }

    ElMessage.warning("调整尺寸后组件重叠，已恢复到原尺寸");
  }

  // 清除碰撞状态
  component.isColliding = false;

  // 清理状态
  resizeState.isResizing = false;
  resizeState.resizeComponent = null;
  resizeState.resizeDirection = "";

  document.removeEventListener("mousemove", handleResizeMove);
  document.removeEventListener("mouseup", handleResizeUp);
};

// 显示对齐线
const showAlignmentGuides = (
  x: number,
  y: number,
  currentComponent: CanvasComponent
) => {
  alignmentGuides.vertical = null;
  alignmentGuides.horizontal = null;

  const threshold = 5;

  canvasComponents.value.forEach((component: CanvasComponent) => {
    if (component.id === currentComponent.id) return;

    // 垂直对齐线
    if (Math.abs(x - component.position.x) <= threshold) {
      alignmentGuides.vertical = component.position.x;
      currentComponent.position.x = component.position.x;
    } else if (
      Math.abs(x + currentComponent.size.width - component.position.x) <=
      threshold
    ) {
      alignmentGuides.vertical = component.position.x;
      currentComponent.position.x =
        component.position.x - currentComponent.size.width;
    }

    // 水平对齐线
    if (Math.abs(y - component.position.y) <= threshold) {
      alignmentGuides.horizontal = component.position.y;
      currentComponent.position.y = component.position.y;
    } else if (
      Math.abs(y + currentComponent.size.height - component.position.y) <=
      threshold
    ) {
      alignmentGuides.horizontal = component.position.y;
      currentComponent.position.y =
        component.position.y - currentComponent.size.height;
    }
  });
};

// 更新组件属性
const updateComponentProps = () => {
  // PropertyPanel现在使用localComponent处理数据同步
  // 这里不需要额外处理
};

// 更新组件尺寸
const updateComponentSize = () => {
  // PropertyPanel现在使用localComponent处理数据同步
  // 这里不需要额外处理
};

// 删除组件
const deleteComponent = () => {
  console.log("请求删除组件:", canvasComponents.value, selectedComponent.value);
  if (!selectedComponent.value) return; // 添加null检查

  if (selectedComponent.value.parentId) {
    let ind = canvasComponents.value.findIndex(
      (comp) => comp.id === selectedComponent.value!.parentId
    );
    console.log(ind,  selectedComponent?.value?.gridItemIndex, 'deleteComponent');
    if (ind !== -1) {
      canvasComponents.value[ind]?.children?.splice(
        selectedComponent?.value?.gridItemIndex!,
        1
      );
      console.log(canvasComponents.value[ind]?.children, 'deleteComponent');
    }
  } else {
    let ind = canvasComponents.value.findIndex(
      (comp) => comp.id === selectedComponent?.value?.id
    );
    if (ind !== -1) {
      canvasComponents.value.splice(ind, 1);
    }
  }
  
  console.log(canvasComponents.value, 'deleteComponent');
  selectedComponent.value = null;
};

// 处理组件更新
const handleUpdateComponent = (component: CanvasComponent) => {
  // 组件已经在PropertyPanel中直接更新，这里不需要额外处理
  console.log("组件已更新:", component);
};

// 处理组件复制
const handleCopyComponent = (event: { component: CanvasComponent }) => {
  const component = event.component;
  // 生成唯一的字段名
  const uniqueField = generateUniqueField(
    component.props.field,
    component.type
  );

  // 寻找合适的位置放置复制的组件
  const offset = 1;
  let newX = component.position.x;
  let newY = component.position.y + offset;

  // 考虑CanvasArea中canvas-component的padding (2px)
  const padding = 2;
  const effectiveWidth = component.size.width + padding * 2;
  const effectiveHeight = component.size.height + padding * 2;

  // 首先尝试在组件下方放置，确保有足够的间距
  const belowPosition = {
    x: component.position.x,
    y: component.position.y + component.size.height + offset,
  };

  // 检查下方位置是否可以放置
  if (
    !checkCollision(
      belowPosition.x - padding,
      belowPosition.y - padding,
      effectiveWidth,
      effectiveHeight
    )
  ) {
    // 下方可以放置，使用下方位置
    newX = belowPosition.x;
    newY = belowPosition.y;
  } else {
    // 下方不能放置，newX设为0，newY逐步检测
    newX = 0;
    newY = component.position.y + offset;

    // 逐步检测newY位置，直到找到不重叠的位置
    let attempts = 0;
    const maxAttempts = 10;

    while (attempts < maxAttempts) {
      // 检查当前位置是否与其他组件重叠
      if (
        !checkCollision(
          newX - padding,
          newY - padding,
          effectiveWidth,
          effectiveHeight
        )
      ) {
        break;
      }

      // 如果重叠，尝试下一个位置，使用更大的偏移确保不重叠
      newY += effectiveHeight + offset;
      attempts++;
    }

    // 如果尝试了多次仍然找不到合适位置，使用原始Y位置
    if (attempts >= maxAttempts) {
      newY = component.position.y;
    }
  }

  // 创建组件的副本
  const com = _.cloneDeep(component)
  const copiedComponent: CanvasComponent = {
    ...com,
    id: generateId(),
    props: {
      ...com.props,
      field: uniqueField,
    },
    position: {
      x: newX,
      y: newY,
    },
  };

  canvasComponents.value.push(copiedComponent);
  selectComponent(copiedComponent);
  ElMessage.success("组件已复制");
};

// 计算组件应该放置的位置
const calculateDropPosition = () => {
  // 如果没有组件，放在初始位置
  if (canvasComponents.value.length === 0) {
    return { x: 0, y: 0 };
  }

  // 找到最后一个顶级组件（没有parentId的组件）
  const topLevelComponents = canvasComponents.value.filter(comp => !comp.parentId);
  if (topLevelComponents.length === 0) {
    return { x: 0, y: 0 };
  }

  // 找到Y坐标最大的组件（最下面的组件）
  let bottomComponent = topLevelComponents[0];
  topLevelComponents.forEach(comp => {
    if (comp.position.y + comp.size.height > bottomComponent.position.y + bottomComponent.size.height) {
      bottomComponent = comp;
    }
  });

  // 新组件放在最下面组件的下方，留10px间距
  return {
    x: 0, // 强制靠左
    y: bottomComponent.position.y + bottomComponent.size.height + 10
  };
};

// 处理拖拽悬停
const handleDragHover = (data: { x: number; y: number; event: DragEvent }) => {
  const gridDropResult = checkGridDrop(data.x, data.y);
  console.log(222222)

  // const componentData = event.dataTransfer.getData("component");
  // if (!componentData) return;
  // 获取拖拽的组件数据 - 优先使用dataTransfer，备用currentDragComponent
  let component = currentDragComponent.value;
  
  console.log("handleDragHover 被调用:", data, component);
  

  if (component) {
    // 计算组件应该放置的位置
    const dropPosition = calculateDropPosition();
    
    // 显示阴影在计算出的位置
    dragShadow.value = {
      visible: true,
      x: dropPosition.x,  
      y: dropPosition.y,
      width: '100%',
      height: component.defaultSize.height + 'px',
    };
  }

  if (gridDropResult.isGridDrop && gridDropResult.gridComponent) {
    // 设置拖拽悬停状态
    dragHoverState.value = {
      isHovering: true,
      gridComponent: gridDropResult.gridComponent,
      gridItemIndex: gridDropResult.gridItemIndex,
    };
  } else {
    // 清除拖拽悬停状态
    dragHoverState.value = {
      isHovering: false,
      gridComponent: null,
      gridItemIndex: -1,
    };
  }
};

// 处理拖拽离开
const handleDragLeave = () => {
  // 清除拖拽悬停状态
  dragHoverState.value = {
    isHovering: false,
    gridComponent: null,
    gridItemIndex: -1,
  };
  
  // 隐藏拖拽阴影
  dragShadow.value = {
    visible: false,
    x: 0,
    y: 0,
    width: 0,
    height: 0,
  };
  
  // 清理拖拽状态
  // currentDragComponent.value = null;
};

// 置顶组件
const handleMoveToTop = (id: string) => {
  const index = canvasComponents.value.findIndex((comp) => comp.id === id);
  if (index > -1) {
    const component = canvasComponents.value.splice(index, 1)[0];
    canvasComponents.value.push(component);
  }
};

// 置底组件
const handleMoveToBottom = (id: string) => {
  const index = canvasComponents.value.findIndex((comp) => comp.id === id);
  if (index > -1) {
    const component = canvasComponents.value.splice(index, 1)[0];
    canvasComponents.value.unshift(component);
  }
};

// 打开互斥设置
const handleOpenMutex = (event: { component: CanvasComponent }) => {
  const component = event.component;
  // 选中组件
  selectedComponent.value = component;
  // 打开互斥设置对话框
  mutexDialogVisible.value = true;
};

// 处理互斥配置确认
const handleMutexConfirm = (config: MutexConfig) => {
  if (selectedComponent.value) {
    selectedComponent.value.props.mutexConfig = config;
    mutexDialogVisible.value = false;
    ElMessage.success("互斥设置已保存");
  }
};

// 打开选项关联设置
const handleOpenRelate = (event: { component: CanvasComponent }) => {
  // 选中组件
  selectedComponent.value = event.component;
  // 打开选项关联设置对话框
  relateDialogVisible.value = true;
};

// 处理选项关联配置确认
const handleRelateConfirm = (config: RelateConfig) => {
  if (selectedComponent.value) {
    selectedComponent.value.props.relateConfig = config;
    relateDialogVisible.value = false;
    ElMessage.success("关联设置已保存");
  }
};

// 处理取消互斥
const handleCancelMutex = (event: { component: CanvasComponent }) => {
  // 选中组件
  selectedComponent.value = event.component;
  // 清除互斥配置
  if (selectedComponent.value) {
    selectedComponent.value.props.mutexConfig = {
      enabled: false,
      rules: [],
    };
  }
  ElMessage.success("互斥设置已取消");
};

// 处理取消关联
const handleCancelRelate = (event: { component: CanvasComponent }) => {
  // 选中组件
  selectedComponent.value = event.component;
  // 清除关联配置
  if (selectedComponent.value) {
    selectedComponent.value.props.relateConfig = {
      enabled: false,
      rules: [],
    };
    // // 重新检查关联规则
    // checkRelateRules();
  }
  ElMessage.success("关联设置已取消");
};

// 清空画布
const clearCanvas = () => {
  canvasComponents.value = [];
  selectedComponent.value = null;
};

// 清除选中状态
const clearSelection = () => {
  selectedComponent.value = null;
};

// 预览表单
const previewForm = () => {
  previewVisible.value = true;
};

// 保存表单
const saveForm = () => {
  saveFormVisible.value = true;
};

// 提交预览表单
const submitPreview = (data: Record<string, any>) => {
  console.log("表单数据:", data);

  // 可以在这里添加数据验证逻辑
  const formData: Record<string, any> = {};

  // 递归遍历组件，处理栅格组件的children
  const processComponents = (components: any[]) => {
    components.forEach((component) => {
      if (component.type === "grid" && component.children) {
        // 如果是栅格组件，递归处理其children
        processComponents(component.children);
      } else {
        // 普通组件，使用 field 作为 key 构建表单数据
        const field = component.props?.field;
        if (field && data[field] !== undefined) {
          formData[field] = data[field];
        }
      }
    });
  };

  processComponents(canvasComponents.value.filter((comp) => !comp.parentId));
  console.log(
    "表单：",
    canvasComponents.value.filter((comp) => !comp.parentId)
  );
  console.log("处理后的表单数据:", formData);
  ElMessage.success("表单提交成功，请查看控制台");
};

// 处理保存表单
const handleSaveForm = async (formData: any) => {
  console.log("保存的表单数据:", formData);

  // 按页面展示顺序排序组件（按Y坐标从上到下）
  const sortedComponents = formData.components
    .filter((comp: any) => !comp.parentId)
    .sort((a: any, b: any) => {
      // 首先按Y坐标排序
      if (a.position.y !== b.position.y) {
        return a.position.y - b.position.y;
      }
      // 如果Y坐标相同，按X坐标排序
      return a.position.x - b.position.x;
    });

  let data = {
    ...formData,
    typeName: getTypeName(formData.type),
    question: JSON.stringify(sortedComponents),
  };
  delete data.components;
  await saveQuestionJson(data);
  ElMessage.success("表单保存成功");
};

// 加载编辑模式的数据
const loadEditData = async () => {
  const mode = route.query.mode as string;
  const id = route.query.id as string;

  if (mode === "edit" && id) {
    loading.value = true;
    try {
      const response = await getQuestionById({ id });
      console.log("编辑模式数据:", response);

      if (response && response.question) {
        // 解析问卷数据
        const questionData = JSON.parse(response.question);
        if (Array.isArray(questionData)) {
          canvasComponents.value = questionData;
          ElMessage.success("问卷数据加载成功");
        } else {
          ElMessage.warning("问卷数据格式不正确");
        }
      } else {
        ElMessage.warning("未找到问卷数据");
      }
    } catch (error) {
      console.error("加载问卷数据失败:", error);
      ElMessage.error("加载问卷数据失败");
    } finally {
      loading.value = false;
    }
  }
};

// 页面加载时检查是否为编辑模式
onMounted(() => {
  loadEditData();
  nextTick(() => {
    // 监听事件总线的值变化事件
    console.log("FormBuilder 正在注册事件监听器");
    EventBus.on("open-relate", handleOpenRelate);
    EventBus.on("open-mutex", handleOpenMutex);
    EventBus.on("cancel-mutex", handleCancelMutex);
    EventBus.on("cancel-relate", handleCancelRelate);
    EventBus.on("copy-component", handleCopyComponent);
    EventBus.on("delete-component", deleteComponent);
    console.log("FormBuilder 事件监听器注册完成");
  });
});

// 组件卸载时清理事件监听器
onUnmounted(() => {
  EventBus.off("open-relate", handleOpenRelate);
  EventBus.off("open-mutex", handleOpenMutex);
  EventBus.off("cancel-mutex", handleCancelMutex);
  EventBus.off("cancel-relate", handleCancelRelate);
  EventBus.off("copy-component", handleCopyComponent);
  EventBus.off("delete-component", deleteComponent);
});



// 导出JSON
const exportJson = () => {
  const formConfig = {
    components: canvasComponents.value,
    version: "1.0.0",
    createTime: new Date().toISOString(),
  };

  const blob = new Blob([JSON.stringify(formConfig, null, 2)], {
    type: "application/json",
  });

  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "form-config.json";
  a.click();
  URL.revokeObjectURL(url);
};
</script>

<style scoped lang="scss">
.form-builder {
  display: flex;
  height: 100vh;
  background-color: #f5f5f5;
}
</style>
